﻿using CefSharp;
using CefSharp.WinForms;
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.IO.Packaging;
using System.Threading;
using System.Windows.Forms;
using System.Xml;

namespace jihuang_Player
{
    public partial class PlayerForm : Form
    {
        public string rootpath = "";
        public string projetPath = "";
        private string projetName = "";
        string htmlpath;
        string builxmlPath = "";
        string anxmlPath = "";
        string buildcontext = "";
        public ChromiumWebBrowser chromeBrowser;
        public PlayerForm()
        {
            projetName = "示例项目";
            init();
        }

        public PlayerForm(string content)
        {
            projetName = content;
            this.Text = content;
            init();
        }
        public void init()
        {
            InitializeComponent();
            this.Text = projetName+"-土了个丘";
            if (!MainWindow.debugmode)
            {
                button1.Hide();
                button2.Hide();
            }
            rootpath = System.IO.Directory.GetCurrentDirectory();
            projetPath = rootpath + "\\Project\\" + projetName + "\\";
            htmlpath = @"file:///" + System.Web.HttpUtility.UrlEncode(projetPath.Replace(@"\", @"/")).Replace("%3a", ":").Replace("%2f", "/") + "index.html";
            Console.WriteLine(htmlpath);
            chromeBrowser = new ChromiumWebBrowser("");
            this.Controls.Add(chromeBrowser);
            chromeBrowser.Dock = DockStyle.Fill;

            WindowState = FormWindowState.Maximized;
            chromeBrowser.Load(htmlpath);
            chromeBrowser.FrameLoadEnd += (sender, args) =>
            {
                //Wait for the MainFrame to finish loading
                if (args.Frame.IsMain)
                {
                    XmlDocument buildxml = new XmlDocument();
                    buildxml.LoadXml(File.ReadAllText(builxmlPath));
                    XmlNode node = buildxml.GetElementsByTagName("Build")[0];
                    XmlNodeList symbols = node.SelectNodes("Symbol");
                    foreach (XmlNode node2 in symbols)
                    {
                        XmlNodeList frames = node2.SelectNodes("Frame");
                        string basename = node2.Attributes["name"].Value;
                        foreach (XmlNode frame in frames)
                        {
                            string pngname = frame.Attributes["image"].Value + ".png";
                            string pngPath = projetPath + pngname;
                            Console.WriteLine(pngPath);
                            Bitmap bitmap = new Bitmap(pngPath);
                            frame.Attributes["w"].Value = "" + bitmap.Width;
                            frame.Attributes["h"].Value = "" + bitmap.Height;
                            bitmap.Dispose();
                        }
                    }
                    buildxml.Save(builxmlPath);
                    buildcontext = (File.ReadAllText(builxmlPath).Replace("\n", "").Replace("\r", ""));
                    args.Frame.ExecuteJavaScriptAsync("var buildcontext='" + buildcontext + "';buildfile(buildcontext);");
                    args.Frame.ExecuteJavaScriptAsync(@" $.get('animation.xml', function (data) {buildan(data);$('#loading').hide();});");
                }
            };

            chromeBrowser.LoadingStateChanged += (sender, args) =>
            {
                //Wait for the Page to finish loading
                if (args.IsLoading == false)
                {
                    chromeBrowser.ExecuteScriptAsync("$('#main').css('opacity','1');");
                }
            };

            builxmlPath = projetPath + "\\build.xml";
            anxmlPath = projetPath + "\\animation.xml";
            chromeBrowser.JavascriptObjectRepository.Register("MyMethd", new MyMethd(this), false);
        }

        private void PlayerForm_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            chromeBrowser.Load(htmlpath);
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            chromeBrowser.ShowDevTools();
        }
    }

    public class MyMethd
    {
        PlayerForm pf;
        private string getString2(string str)
        {
            return str.Replace("\r", "").Replace("\n", "");
        }
        public MyMethd(PlayerForm p)
        {
            pf = p;
        }

        public string getString(string str)
        {
            str = (str.Replace(@"\", @"\\").Replace("'", @"\'").Replace("\n", @"\n").Replace("\r\\n", @"\n"));
            return str;
        }
        public string getinfo()
        {
            return "卧槽";
        }

        public void showInFileMarnerge()
        {
            System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe");
            psi.Arguments = "/e,/select," + pf.projetPath + @"index.html";
            System.Diagnostics.Process.Start(psi);
        }
        public void openThisPng(string name)
        {
            System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo("Explorer.exe");
            psi.Arguments = "/e,/select," + pf.projetPath + name + ".png";
            Console.WriteLine(psi.Arguments);
            System.Diagnostics.Process.Start(psi);
        }

        public void replaceCurrentPicture(string name)
        {
            string pngPath = pf.projetPath + name + ".png";
            if (File.Exists(pngPath))
            {
                Thread thread = new Thread(new ThreadStart(() =>
                {
                    using (OpenFileDialog openFileDialog = new OpenFileDialog())
                    {
                        openFileDialog.Filter = "(*.png)|*.png";
                        openFileDialog.RestoreDirectory = true;
                        if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                        {
                            //Get the path of specified file
                            string opeanpngpath = openFileDialog.FileName;
                            try
                            {
                                Bitmap bitmap = new Bitmap(opeanpngpath);
                                File.Copy(opeanpngpath, pngPath, true);
                                pf.chromeBrowser.ExecuteScriptAsync("replacepicture('" + name + "'," + bitmap.Width + "," + bitmap.Height + ");");
                            }
                            catch (ArgumentException e)
                            {
                                pf.chromeBrowser.ExecuteScriptAsync("showerror('加载图片失败！');");
                                Console.WriteLine(e);
                            }
                        }
                        else
                        {
                            Console.WriteLine("取消更换图片");
                        }
                    }
                }
                    ));
                thread.SetApartmentState(ApartmentState.STA);
                thread.Start();
            }
            else
            {
                MessageBox.Show("找不到文件：" + pngPath);
            }
        }

        public void reloadCurrentPicture(string name)
        {
            string pngPath = pf.projetPath + name + ".png";
            if (File.Exists(pngPath))
            {
                Bitmap bitmap = new Bitmap(pngPath);
                pf.chromeBrowser.ExecuteScriptAsync("replacepicture('" + name + "'," + bitmap.Width + "," + bitmap.Height + ");");
            }
            else
            {
                pf.chromeBrowser.ExecuteScriptAsync("showerror('找不到" + getString(pf.projetPath + name) + ".png');");
            }
        }

        public void savebuild(string data)
        {
            try
            {
                File.WriteAllText(pf.projetPath + "build.xml", data);
            }
            catch (Exception e)
            {
                pf.chromeBrowser.ExecuteScriptAsync("showerror('" + getString(e.ToString()) + "');");
            }
            pf.chromeBrowser.ExecuteScriptAsync("$('#loading').hide();");
        }


        private void loadAn(bool flag)
        {
            Thread thread = new Thread(new ThreadStart(() =>
            {
                using (OpenFileDialog openFileDialog = new OpenFileDialog())
                {
                    openFileDialog.InitialDirectory = pf.rootpath + @"\resources\内置动画";
                    openFileDialog.Filter = "anim.bin,animation.xml|*.bin;*.xml;*zip";
                    openFileDialog.RestoreDirectory = flag;
                    if (openFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        string[] name = openFileDialog.SafeFileName.Split('.');
                        string exname = name[name.Length - 1];
                        switch (exname)
                        {
                            case "xml":
                                pf.chromeBrowser.ExecuteScriptAsync("var otherxml='" + getString2(File.ReadAllText(openFileDialog.FileName)) + "'; loadothrXml(otherxml);");
                                break;
                            case "bin":
                                pf.chromeBrowser.ExecuteScriptAsync("var otherxml='" + getString2(new Debin(openFileDialog.FileName).decodean()) + "'; loadothrXml(otherxml);");
                                break;
                            case "zip":
                                pf.chromeBrowser.ExecuteScriptAsync("var otherxml='" + getString2(new Debin(openFileDialog.FileName).decodeanzip()) + "'; loadothrXml(otherxml);");
                                break;
                            default: pf.chromeBrowser.ExecuteScriptAsync("showerror('" + getString("未找到动画内容") + "');"); break;
                        }
                    }
                    else
                    {
                        pf.chromeBrowser.ExecuteScriptAsync("$('#loading').hide();");
                    }
                }
            }));
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
        }
        public void loadBuiltinAn()
        {
            loadAn(false);
        }

        public void loadExternalAn()
        {
            loadAn(true);
        }

        public void compilation()
        {
            Thread t = new Thread(new ThreadStart(() =>
            {
                new Compilation(pf.projetPath).ShowDialog();
            }));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
        }
    }
}
